package com.fy.customview.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.fy.customview.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 涟漪效果
 * https://github.com/zhuwentao2150/RippleView
 * <p>
 * Created by zhuwentao on 2018-03-07.
 */
public class RippleView extends View {

    private final String TAG = "RippleView";

    private Context mContext;

    // 画笔对象
    private Paint mPaint;

    // View宽
    private float mWidth;

    // View高
    private float mHeight;

    // 声波的圆圈集合
    private List<Circle> mRipples;

    private int sqrtNumber;

    // 圆圈扩散的速度
    private int mSpeed;

    // 圆圈之间的密度
    private int mDensity;

    // 圆圈的颜色
    private int mColor;

    // 圆圈是否为填充模式
    private boolean mIsFill;

    // 圆圈是否为渐变模式
    private boolean mIsAlpha;

    public RippleView(Context context) {
        this(context, null);
    }

    public RippleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RippleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 获取用户配置属性
        TypedArray tya = context.obtainStyledAttributes(attrs, R.styleable.RippleView);
        mColor = tya.getColor(R.styleable.RippleView_cColor, Color.BLUE);
        mSpeed = tya.getInt(R.styleable.RippleView_cSpeed, 1);
        mDensity = tya.getInt(R.styleable.RippleView_cDensity, getResources().getDimensionPixelSize(R.dimen.dp_10));
        mIsFill = tya.getBoolean(R.styleable.RippleView_cIsFill, false);
        mIsAlpha = tya.getBoolean(R.styleable.RippleView_cIsAlpha, false);
        tya.recycle();

        init();
    }

    private void init() {
        mContext = getContext();

        // 设置画笔样式
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.dp_1));
        if (mIsFill) {
            mPaint.setStyle(Paint.Style.FILL);
        } else {
            mPaint.setStyle(Paint.Style.STROKE);
        }
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setAntiAlias(true);

        // 添加第一个圆圈
        mRipples = new ArrayList<>();
        Circle c = new Circle(0, 255);
        mRipples.add(c);


        // 设置View的圆为半透明
        setBackgroundColor(Color.TRANSPARENT);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //圆弧
        drawArc(canvas);

        // 内切正方形
//        drawInCircle(canvas);

        // 外切正方形
        // drawOutCircle(canvas);
    }

    /**
     * 圆到宽度
     *
     * @param canvas
     */
    private void drawInCircle(Canvas canvas) {
//        canvas.save();

        // 处理每个圆的宽度和透明度
        for (int i = 0; i < mRipples.size(); i++) {
            Circle c = mRipples.get(i);
            mPaint.setAlpha(c.alpha);// （透明）0~255（不透明）
            canvas.drawCircle(mWidth / 2, mHeight / 2, c.width - mPaint.getStrokeWidth(), mPaint);

            // 当圆超出View的宽度后删除
            if (c.width > mWidth / 2) {
                mRipples.remove(i);
            } else {
                // 计算不透明的数值
                if (mIsAlpha) {
                    double alpha = 255 - c.width * (255 / (mWidth / 2.0));
                    c.alpha = (int) alpha;
                }
                // 修改这个值控制速度
                c.width += mSpeed;
            }
        }


        // 里面添加圆
        if (mRipples.size() > 0) {
            // 控制第二个圆出来的间距
            if (mRipples.get(mRipples.size() - 1).width > mDensity) {
                mRipples.add(new Circle(0, 255));
            }
        }


        invalidate();

//        canvas.restore();
    }


    private class Arc {
        private int alpha;
        private int startAngle = -60;
        private int sweepAngle = -60;
        private float topFlag = 0;
        private RectF rectF = new RectF();
    }

    private ArrayList<Arc> arcs = new ArrayList<>();
    private ArrayList<Arc> arcBacks = new ArrayList<>();

    private void initArc() {
        if (arcs.size() == 0) {
            Arc arc = new Arc();
            arc.rectF.left = mWidth / 2;
            arc.rectF.top = mHeight - 20;
            arc.rectF.right = mWidth / 2;
            arc.rectF.bottom = mHeight;
            arc.topFlag = mHeight;
            arcs.add(arc);
        }

    }

    private void drawArc(Canvas canvas) {
        for (int i = 0; i < arcs.size(); i++) {
            Arc arc = arcs.get(i);
            RectF rectF = arc.rectF;
            arc.alpha = (int) (255 * (1 - rectF.height() / arc.topFlag / 2));
            mPaint.setAlpha(arc.alpha);
            canvas.drawArc(rectF, arc.startAngle, arc.sweepAngle, false, mPaint);
            rectF.left -= mSpeed;
            rectF.top -= (mSpeed + 1);
            rectF.right += mSpeed;
            if (rectF.top <= 0) {
                //已经到达终点的圆弧把它扔了
                Arc arcBack = arcs.remove(i);
                arc.rectF.top = 0;
                arc.rectF.bottom = arc.rectF.top + mSpeed;
                arc.startAngle = 60;
                arc.sweepAngle = 60;
                arcBacks.add(arcBack);
            }
        }
        if (arcs.size() > 0) {
            if (arcs.get(arcs.size() - 1).rectF.width() > mDensity) {
                Arc arcNew = new Arc();
                arcNew.topFlag = mHeight;
                arcNew.rectF.left = mWidth / 2;
                arcNew.rectF.top = mHeight - 20;
                arcNew.rectF.right = mWidth / 2;
                arcNew.rectF.bottom = mHeight;
                arcs.add(arcNew);
            }
        }
        for (int i = 0; i < arcBacks.size(); i++) {
            Arc arc = arcBacks.get(i);
            RectF rectF = arc.rectF;
            arc.alpha = (int) (126 - 255 * (rectF.height() / arc.topFlag / 2f));
            if (arc.alpha < 0) {//有时候高度超出设置的标志会导致计算出来的透明度为-1
                arc.alpha = 0;
            }
            mPaint.setAlpha(arc.alpha);
            canvas.drawArc(rectF, arc.startAngle, arc.sweepAngle, false, mPaint);
            rectF.left -= mSpeed;
            rectF.bottom += (mSpeed + 1);
            rectF.right += mSpeed;
            if (rectF.bottom >= mHeight) {
                //已经到达终点的圆弧把它扔了
                arcBacks.remove(i);

            }
        }
        mPaint.setAlpha(255);
        invalidate();
    }

    /**
     * 圆到对角线
     *
     * @param canvas
     */
    private void drawOutCircle(Canvas canvas) {
        canvas.save();

        // 使用勾股定律求得一个外切正方形中心点离角的距离
        sqrtNumber = (int) (Math.sqrt(mWidth * mWidth + mHeight * mHeight) / 2);

        // 变大
        for (int i = 0; i < mRipples.size(); i++) {

            // 启动圆圈
            Circle c = mRipples.get(i);
            mPaint.setAlpha(c.alpha);// （透明）0~255（不透明）
            canvas.drawCircle(mWidth / 2, mHeight / 2, c.width - mPaint.getStrokeWidth(), mPaint);

            // 当圆超出对角线后删掉
            if (c.width > sqrtNumber) {
                mRipples.remove(i);
            } else {
                // 计算不透明的度数
                double degree = 255 - c.width * (255 / (double) sqrtNumber);
                c.alpha = (int) degree;
                c.width += 1;
            }
        }

        // 里面添加圆
        if (mRipples.size() > 0) {
            // 控制第二个圆出来的间距
            if (mRipples.get(mRipples.size() - 1).width == 50) {
                mRipples.add(new Circle(0, 255));
            }
        }
        invalidate();
        canvas.restore();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int myWidthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int myWidthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int myHeightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int myHeightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        // 获取宽度
        if (myWidthSpecMode == MeasureSpec.EXACTLY) {
            // match_parent
            mWidth = myWidthSpecSize;
        } else {
            // wrap_content
            mWidth = getResources().getDimensionPixelSize(R.dimen.dp_120);
        }

        // 获取高度
        if (myHeightSpecMode == MeasureSpec.EXACTLY) {
            mHeight = myHeightSpecSize;
        } else {
            // wrap_content
            mHeight = getResources().getDimensionPixelSize(R.dimen.dp_120);
        }

        //设置第一个弧的初始位置
        initArc();

        // 设置该view的宽高
        setMeasuredDimension((int) mWidth, (int) mHeight);
    }


    class Circle {
        Circle(int width, int alpha) {
            this.width = width;
            this.alpha = alpha;
        }

        int width;

        int alpha;
    }

}